package com.heima.search.service.impl;

import com.heima.common.dtos.ResponseResult;
import com.heima.model.search.dtos.ArticleDocumentVo;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ArticleDoc;
import com.heima.search.service.ApArticleSearchService;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * ES索引业务层 实现
 */
@Service
public class ApArticleSearchServiceImpl implements ApArticleSearchService {

    private static final String INDEX_NAME = "article";

    @Autowired
    private RestHighLevelClient highLevelClient;

    /**
     * 搜索文章
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {
        //参数校验
        if(dto.getPageSize()<0 || dto.getPageSize()>=100)dto.setPageSize(20);
        if(dto.getMinBehotTime()==null) dto.setMinBehotTime(new Date());

        try {
            //拼接各种条件
            SearchRequest request = new SearchRequest(INDEX_NAME);

            //query
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            if(StringUtils.isBlank(dto.getSearchWords())){
                boolQueryBuilder.must(QueryBuilders.matchAllQuery());
            }else{
                boolQueryBuilder.must(QueryBuilders.matchQuery("title",dto.getSearchWords()));
            }

            boolQueryBuilder.filter(QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime().getTime()));
            request.source().query(boolQueryBuilder);

            //分页
            request.source().size(20);

            //排序
            request.source().sort(SortBuilders.fieldSort("publishTime").order(SortOrder.DESC));

            //高亮
            request.source().highlighter(new HighlightBuilder().field("title")
                    .requireFieldMatch(true)
                    .preTags("<font style='color: red; font-size: inherit;'>")
                    .postTags("</font>"));

            //执行查询，获取结果
            SearchResponse response = highLevelClient.search(request, RequestOptions.DEFAULT);

            //封装结果，返回结果
            SearchHits hits = response.getHits();

            //获取总结果数
            long total = hits.getTotalHits().value;
            System.out.println("结果数："+total);

            List<ArticleDocumentVo> list = new ArrayList<>();

            //遍历命中结果
            for(SearchHit hit:hits){
                String json = hit.getSourceAsString();
                ArticleDoc articleDoc = JsonUtils.toBean(json, ArticleDoc.class);

                ArticleDocumentVo vo = BeanHelper.copyProperties(articleDoc,ArticleDocumentVo.class);

                //获取高亮内容并设置字段
                HighlightField highlightField = hit.getHighlightFields().get("title");
                if(highlightField!=null){
                    vo.setH_title(highlightField.getFragments()[0].toString());
                }

                list.add(vo);
            }

            return ResponseResult.okResult(list);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
}
